/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package APIs;

import bllobjects.Account;
import chat.ChatServer;
import chat.TextChatMessage;
import chat.room.ChatRoom;
import dalfactory.SDALFactory;
import fsktms.request.RequestParameters;
import fsktms.request.RequestRespond;
import fsktms.request.api.RequestAPIGroup;
import java.rmi.RemoteException;
import java.util.ArrayList;
import java.util.logging.Level;
import java.util.logging.Logger;
import utils.DataRow;
import utils.DataTable;

/**
 *
 * @author salm
 */
public class ChatAPIs extends RequestAPIGroup
{
    private ChatServer chatServer;
    
    public ChatAPIs(ChatServer chatSv)
    {
        super("Chat");
        
        this.chatServer = chatSv;
    }
    
    public RequestRespond getHistoryMessage(RequestParameters params)
    {
        RequestRespond resultParams = new RequestRespond();
        String receiver = (String) params.get("ReceiverID");
        
        try {
            DataTable dt = SDALFactory.getInstance().getMessage().getAllMessageTo(receiver);
            ArrayList<TextChatMessage> messages = new ArrayList();
            for (int i = 0; i < dt.size(); ++i)
            {
                DataRow row = dt.get(i);
                messages.add(new TextChatMessage(row.get("Sender"), row.get("Receiver"), row.get("Content")));
            }
            
            resultParams.setResult(messages); 
        } catch (RemoteException ex) {
            Logger.getLogger(AccountAPIs.class.getName()).log(Level.SEVERE, null, ex);
            RequestRespond.setFailure(resultParams, RequestParameters.VALUE_FAILURE_CODE_SERVER_ERROR, ex.getMessage());
        }
        
        return resultParams;
    }
    
    public RequestRespond getConversation(RequestParameters params)
    {
        RequestRespond resultParams = new RequestRespond();
        String user1 = (String) params.get("User1");
        String user2 = (String) params.get("User2");
        
        try {
            DataTable dt = SDALFactory.getInstance().getMessage().getConversation(user1, user2);
            ArrayList<TextChatMessage> messages = new ArrayList();
            for (int i = 0; i < dt.size(); ++i)
            {
                DataRow row = dt.get(i);
                messages.add(new TextChatMessage(row.get("Sender"), row.get("Receiver"), row.get("Content")));
            }
            
            resultParams.setResult(messages); 
        } catch (RemoteException ex) {
            Logger.getLogger(AccountAPIs.class.getName()).log(Level.SEVERE, null, ex);
            RequestRespond.setFailure(resultParams, RequestParameters.VALUE_FAILURE_CODE_SERVER_ERROR, ex.getMessage());
        }
        
        return resultParams;
    }
    
    // room APIs
    public RequestRespond getAllRoomID(RequestParameters params)
    {
        RequestRespond resultParams = new RequestRespond();
        ArrayList<String> rooms = new ArrayList(this.chatServer.getRoomIDs());
        resultParams.setResult(rooms);
        
        return resultParams;
    }
    
    public RequestRespond getAllRoomDescription(RequestParameters params)
    {
        RequestRespond resultParams = new RequestRespond();
        ArrayList<String> roomDescs = new ArrayList(this.chatServer.getRoomIDs().size());
        for (ChatRoom chatRoom : this.chatServer.getRooms())
        {
            roomDescs.add(chatRoom.toString());
        }
        resultParams.setResult(roomDescs);
        
        return resultParams;
    }
    
    public RequestRespond getRoomUsers(RequestParameters params)
    {
        String roomID = (String) params.get("RoomID");
        RequestRespond resultParams = new RequestRespond();
        ChatRoom room = this.chatServer.getRoom(roomID);
        if (room != null)
        {
            ArrayList<Account> users = new ArrayList<>();
            for (String user : room.getUsers())
            {
                DataTable dtUserAccount;
                try 
                {
                    dtUserAccount = SDALFactory.getInstance().getAccount().getAccount(user);
                    if (dtUserAccount != null && dtUserAccount.size() > 0)
                    {
                        DataRow row = dtUserAccount.get(0);
                        users.add(new Account(row.get("UserID"), row.get("UserName"),
                                    Integer.parseInt(row.get("Experience")),
                                    Integer.parseInt(row.get("Level")),
                                    row.get("TypeID")));
                    }
                } catch (RemoteException ex)
                {
                    Logger.getLogger(ChatAPIs.class.getName()).log(Level.SEVERE, null, ex);
                }
            }
            resultParams.setResult(users);
        }
        else
        {
            resultParams.setFailure(RequestRespond.VALUE_FAILURE_CODE_NOT_FOUND, "RoomID doesn't exist");
        }
        
        return resultParams;
    }
    
    public RequestRespond getRoomUserIDs(RequestParameters params)
    {
        String roomID = (String) params.get("RoomID");
        RequestRespond resultParams = new RequestRespond();
        ChatRoom room = this.chatServer.getRoom(roomID);
        if (room != null)
        {
            ArrayList<String> users = new ArrayList<>();
            for (String user : room.getUsers())
            {
                users.add(user);
            }
            resultParams.setResult(users);
        }
        else
        {
            resultParams.setFailure(RequestRespond.VALUE_FAILURE_CODE_NOT_FOUND, "RoomID doesn't exist");
        }
        
        return resultParams;
    }
    
    public RequestRespond createRoom(RequestParameters params)
    {
        String roomID = (String) params.get("RoomID");
        String roomName = (String) params.get("RoomName");
        String owner = (String) params.get("Owner");
        RequestRespond resultParams = new RequestRespond();
        if (!this.chatServer.getRoomIDs().contains(roomID))
        {
            try {
                SDALFactory.getInstance().getRoom().insertRoom(Integer.parseInt(roomID), roomName, 0);
                this.chatServer.addRoom(new ChatRoom(roomID, roomName));
                this.chatServer.getRoom(roomID).addUser(roomID);
                resultParams.setResult(true);
            } catch (RemoteException ex) {
                Logger.getLogger(ChatAPIs.class.getName()).log(Level.SEVERE, null, ex);
            resultParams.setFailure(RequestRespond.VALUE_FAILURE_CODE_ERROR, "Server error");
            }
        }
        else
        {
            resultParams.setFailure(RequestRespond.VALUE_FAILURE_CODE_ERROR, "Room already exists");
        }
        
        return resultParams;
    }
    
    public RequestRespond joinRoom(RequestParameters params)
    {
        String roomID = (String) params.get("RoomID");
        String joiner = (String) params.get("UserID");
        RequestRespond resultParams = new RequestRespond();
        ChatRoom room = this.chatServer.getRoom(roomID);
        if (room != null)
        {
            if (room.addUser(joiner))
            {
                resultParams.setResult(true);
            }
            else
            {
                resultParams.setFailure(RequestRespond.VALUE_FAILURE_CODE_ERROR, "User already joined");
            }
        }
        else
        {
            resultParams.setFailure(RequestRespond.VALUE_FAILURE_CODE_NOT_FOUND, "RoomID doesn't exist");
        }
        
        return resultParams;
    }
    
    public RequestRespond leaveRoom(RequestParameters params)
    {
        String roomID = (String) params.get("RoomID");
        String leaver = (String) params.get("UserID");
        RequestRespond resultParams = new RequestRespond();
        ChatRoom room = this.chatServer.getRoom(roomID);
        if (room != null)
        {
            if (room.removeUser(leaver))
            {
                resultParams.setResult(true);
            }
            else
            {
                resultParams.setFailure(RequestRespond.VALUE_FAILURE_CODE_ERROR, "User doesn't in this room");
            }
        }
        else
        {
            resultParams.setFailure(RequestRespond.VALUE_FAILURE_CODE_NOT_FOUND, "RoomID doesn't exist");
        }
        
        return resultParams;
    }
    
    public RequestRespond listenRoom(RequestParameters params)
    {
        String roomID = (String) params.get("RoomID");
        String joiner = (String) params.get("UserID");
        RequestRespond resultParams = new RequestRespond();
        ChatRoom room = this.chatServer.getRoom(roomID);
        if (room != null)
        {
            if (room.addListenUser(joiner))
            {
                resultParams.setResult(true);
            }
            else
            {
                resultParams.setFailure(RequestRespond.VALUE_FAILURE_CODE_ERROR, "User doesn't in this room");
            }
        }
        else
        {
            resultParams.setFailure(RequestRespond.VALUE_FAILURE_CODE_NOT_FOUND, "RoomID doesn't exist");
        }
        
        return resultParams;
    }
    
    public RequestRespond muteRoom(RequestParameters params)
    {
        String roomID = (String) params.get("RoomID");
        String leaver = (String) params.get("UserID");
        RequestRespond resultParams = new RequestRespond();
        ChatRoom room = this.chatServer.getRoom(roomID);
        if (room != null)
        {
            if (room.removeListenUser(leaver))
            {
                resultParams.setResult(true);
            }
            else
            {
                resultParams.setFailure(RequestRespond.VALUE_FAILURE_CODE_ERROR, "User doesn't in this room");
            }
        }
        else
        {
            resultParams.setFailure(RequestRespond.VALUE_FAILURE_CODE_NOT_FOUND, "RoomID doesn't exist");
        }
        
        return resultParams;
    }
}